﻿using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using CultivationSkills.Utils;
using ThunderRoad;
using UnityEngine;

namespace CultivationSkills.Skills;

[SuppressMessage("ReSharper", "MemberCanBePrivate.Global")]
[SuppressMessage("ReSharper", "FieldCanBeMadeReadOnly.Global")]
[SuppressMessage("ReSharper", "ConvertToConstant.Global")]
[SuppressMessage("ReSharper", "ClassNeverInstantiated.Global")]
public class SkillFlyBySword : ThunderScript
{
    public static ModOptionFloat[] MoveSpeedOptions = ModOptionFloat.CreateArray(1f, 100f, 1f);

    [ModOption(name = "Enabled", order = 1, category = "Fly By Sword")]
    public static bool Enabled = true;

    [ModOption(name = "Fly Speed", order = 1, valueSourceName = "MoveSpeedOptions", category = "Fly By Sword",
        interactionType = ModOption.InteractionType.Slider)]
    public static float MoveSpeed = 5.0f; // 飞行速度，可以根据需要调整

    private Rigidbody _playerRigidbody;
    private PlayerControl.Hand _leftControlHand;
    private PlayerControl.Hand _rightControlHand;

    private readonly Dictionary<Side, Transform> _handleItemsForwards = new();
    private readonly Dictionary<Side, Item> _handleItemsItems = new();
    private readonly Dictionary<Side, bool> _handleItemsFlags = new();

    public override void ScriptLoaded(ModManager.ModData modData)
    {
        base.ScriptLoaded(modData);
        Init();
    }

    public override void ScriptUnload()
    {
        base.ScriptUnload();
        Clear();
    }

    public void Init()
    {
        if (!Player.local)
        {
            return;
        }

        _playerRigidbody = Player.local.GetComponent<Rigidbody>();
        if (!_playerRigidbody)
        {
            return;
        }
        _leftControlHand = Player.local.handLeft.controlHand;
        _rightControlHand = Player.local.handRight.controlHand;

        EventManager.OnItemGrab -= OnItemGrab;
        EventManager.OnItemRelease -= OnItemRelease;
        EventManager.OnItemGrab += OnItemGrab;
        EventManager.OnItemRelease += OnItemRelease;
    }

    public void Clear()
    {
        EventManager.OnItemGrab -= OnItemGrab;
        EventManager.OnItemRelease -= OnItemRelease;
    }

    private void OnItemRelease(Handle handle, RagdollHand ragdollHand, bool throwing)
    {
        Debug.Log("Item release:" + ragdollHand.side);
        _handleItemsForwards.Remove(ragdollHand.side);
        _handleItemsItems.Remove(ragdollHand.side);
        if (_handleItemsFlags[ragdollHand.side])
        {
            // 去除俯冲打击
            handle.item.data.flags |= ItemFlags.Jabbing;
        }
    }

    private void OnItemGrab(Handle handle, RagdollHand ragdollHand)
    {
        Debug.Log("抓住:" + handle.item.name);
        _handleItemsForwards[ragdollHand.side] = GameUtils.GetItemForwardTransform(handle.item);
        _handleItemsItems[ragdollHand.side] = handle.item;
        _handleItemsFlags[ragdollHand.side] = handle.item.data.HasFlag(ItemFlags.Jabbing);
        if (_handleItemsFlags[ragdollHand.side])
        {
            handle.item.data.flags &= ~ItemFlags.Jabbing;
        }
    }

    public override void ScriptFixedUpdate()
    {
        if (!Enabled || !_playerRigidbody)
        {
            return;
        }
        DoFly();
    }

    private void DoFly()
    {
        // 落地恢复
        _playerRigidbody.useGravity = Player.local.locomotion.isGrounded;
        _playerRigidbody.isKinematic = !_playerRigidbody.useGravity;
        Debug.Log($"DoFly:{_leftControlHand.alternateUsePressed},{_rightControlHand.alternateUsePressed}");
        if (_rightControlHand.alternateUsePressed && _handleItemsForwards.TryGetValue(Side.Left, out var forward))
        {
            var move = forward.forward * (MoveSpeed * Time.deltaTime);
            Player.local.locomotion.transform.position += move;
            _handleItemsItems[Side.Left].transform.position += move;
        }

        if (_leftControlHand.alternateUsePressed && _handleItemsForwards.TryGetValue(Side.Right, out var forwardRight))
        {
            Debug.Log("isGrounded:"+Player.local.locomotion.isGrounded+",isJumping:"+Player.local.locomotion.isJumping);
            var move = forwardRight.forward * (MoveSpeed * Time.deltaTime);
            Player.local.locomotion.transform.position += move;
            _handleItemsItems[Side.Right].transform.position += move;
        }

        if (_playerRigidbody.useGravity)
        {
            return;
        }
        if (PlayerControl.local.jumpPressed)
        {
            _playerRigidbody.AddForce(new Vector3(0, MoveSpeed * Time.deltaTime, 0), ForceMode.Impulse);
        }

        if (Player.local.crouching)
        {
            _playerRigidbody.AddForce(new Vector3(0, -MoveSpeed * Time.deltaTime, 0), ForceMode.Impulse);
        }
    }

    public static void ChangeFlyStatus(bool fly)
    {
        Debug.Log("Fly:" + fly);
        if (!Player.local)
        {
            return;
        }

        var rb = Player.local.GetComponent<Rigidbody>();
        if (!rb) return;
        rb.useGravity = !fly;
    }
}